// C source file with the function definitions to handle BMD's MAT3 section

// check_j3dgraph_bmd_mat3() function
// function to check if the MAT3 section of a BMD is valid
j3dgraph_bmd_mat3_err_cd check_j3dgraph_bmd_mat3(j3dgraph * file)
{
  // check params
  if (file == NULL)
    goto err;
  // check the MAT3 character array at section start
  if (comp_bytes(((j3dgraph_gen_sec *) (file -> SEC)[J3DGRAPH_BMD_MAT3_POS]) -> START,
                 J3DGRAPH_BMD_SEC_START[J3DGRAPH_BMD_MAT3_POS][file -> ENDIAN - 1], 4) == 0)
    goto err;
  
  // TODO: add more checks
  
  // all good
  return J3DGRAPH_BMD_MAT3_ERR_NO_ERR;
  
  // invalid section
  err:
  return J3DGRAPH_BMD_MAT3_ERR_HEADER;
}

// append_j3dgraph_bmd_mat3() function
// append a j3dgraph_bmd_mat3 struct to an incomplete j3dgraph struct
j3dgraph_bmd_mat3 * append_j3dgraph_bmd_mat3(j3dgraph * file)
{
  // check if the section is valid
  j3dgraph_bmd_mat3 * mat3 = NULL;
  j3dgraph_bmd_mat3_err_cd err_cd = check_j3dgraph_bmd_mat3(file);
  if (err_cd < J3DGRAPH_BMD_MAT3_ERR_NO_ERR)
    goto err;
  
  // otherwise append the structure to j3dgraph
  mat3 = allocate_memory(1, sizeof(j3dgraph_bmd_mat3));
  if (mat3 == NULL)
    goto err;
  
  // fill the structure  
  // TODO: research the MAT3 structure
  
  // temp variables
  umax tmp = 0;
  j3dgraph_gen_sec * sec = (file -> SEC)[J3DGRAPH_BMD_MAT3_POS];
  byte * ptr = (sec -> START) + 8;
  
  // my additions
  mat3 -> PATH = file -> PATH;
  mat3 -> ENDIAN = file -> ENDIAN;
  mat3 -> ERR_CD = err_cd;
  // actual structure
  mat3 -> START = sec -> START;
  mat3 -> SIZE = sec -> SIZE;  
  mat3 -> MAT_CNT = ptr; ptr += 2;   
  // get material count
  /* umax mat_count = get_std_uint(16, mat3 -> MAT_CNT, file -> ENDIAN); */
    
  // skip 10 bytes
  ptr += 10;  
  mat3 -> MAT_STR_TB_OFFSET = ptr; ptr += 4;
  
  // skip until material name table
  // ...
  
  // create the joint string table
  ptr = (mat3 -> START) + get_std_uint(32, mat3 -> MAT_STR_TB_OFFSET, file -> ENDIAN);
  tmp = get_j3dgraph_str_tb_size(ptr, (file -> DATA) + (file -> FSIZE) - ptr, file -> ENDIAN);
  if (tmp == 0)
    goto err;
  mat3 -> MAT_STR_TB = get_j3dgraph_str_tb(ptr, (file -> DATA) + (file -> FSIZE) - ptr, file -> ENDIAN);
  if ((mat3 -> MAT_STR_TB) == NULL)
    goto err;
  ptr += tmp;
  
  // remove the j3dgraph_gen_sec and append the new one
  free_memory((file -> SEC)[J3DGRAPH_BMD_MAT3_POS]);
  return ((file -> SEC)[J3DGRAPH_BMD_MAT3_POS] = mat3);
  // invalid section
  err:
  free_memory(mat3);
  return NULL;
}

// remove_j3dgraph_bmd_mat3() function
// function to remove a j3dgraph_bmd_mat3 structure from a j3dgraph structure
void remove_j3dgraph_bmd_mat3(j3dgraph * file)
{
  // check params
  if (file == NULL || (file -> SEC) == NULL)
    return;
  // free the memory allocated by append_j3dgraph_bmd_mat3()
  close_j3dgraph_str_tb(((j3dgraph_bmd_mat3 *) (file -> SEC)[J3DGRAPH_BMD_MAT3_POS]) -> MAT_STR_TB);
  free_memory((file -> SEC)[J3DGRAPH_BMD_MAT3_POS]);
  return;
}

// print_j3dgraph_bmd_mat3() function
// print the information of the MAT3 section of a BMD
void print_j3dgraph_bmd_mat3(j3dgraph_bmd_mat3 * mat3)
{
  // check ptr
  if (mat3 == NULL ||  (mat3 -> ERR_CD) < J3DGRAPH_BMD_MAT3_ERR_NO_ERR)
    return;
  
  // starting visual queue
  printf("\n### J3DGraph MAT3 section info start ###\n\n");
  
  // file info
  printf("File: %s\n", mat3 -> PATH);
  printf("Section endian: %s\n", mat3 -> ENDIAN == BIG ? "BIG" : "LITTLE");
  printf("Section error code: %u\n", mat3 -> ERR_CD);
  
  // section header
  printf("\nSection start: ");
  print_ascii_arr(mat3 -> START, 4);
  printf("Section size (bytes): %llu\n", get_std_uint(32, mat3 -> SIZE, mat3 -> ENDIAN));
  
  // TODO: research the MAT3 structure
  
  // get material count
  umax mat_count = get_std_uint(16, mat3 -> MAT_CNT, mat3 -> ENDIAN);
  printf("Material count: %llu\n", mat_count);
  
  // ...
  
  printf("Material name table offset (hex): %08llX\n",
         get_std_uint(32, mat3 -> MAT_STR_TB_OFFSET, mat3 -> ENDIAN));
  
  // ...
  
  // material string table
  printf("\n## Material string table begin:\n");
  print_j3dgraph_str_tb(mat3 -> MAT_STR_TB); 
  
  // ...
  
  // end of structure
  printf("\n### J3DGraph MAT3 section info end ###\n");
  return;
}
